#include <csignal>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
using namespace std;

void handler(int signo)
{
    std::cout << "get a signal: " << signo << std::endl;

    sigset_t set;
    sigprocmask(SIG_BLOCK, nullptr, &set);
    // sigpending(&set);

    for (int sig = 1; sig < 32; sig++)
    {
        if (sigismember(&set, sig))
            cout << '1';
        else
            cout << '0';
    }
    cout << endl;
}

int main()
{
    // signal(SIGINT, handler);
    
    struct sigaction act, oact;
    memset(&act, 0, sizeof(act));
    memset(&oact, 0, sizeof(oact));

    act.sa_handler = handler;
    act.sa_flags = 0;
    sigaddset(&act.sa_mask, 1);
    sigaddset(&act.sa_mask, 3);
    sigaddset(&act.sa_mask, 4);
    sigaddset(&act.sa_mask, 5);

    sigaction(SIGINT, &act, &oact);

    std::cout << "send a signal" << std::endl;
    raise(SIGINT);

    return 0;
}

// void handler(int signo)
// {
//     std::cout << "get a signal: " << signo << std::endl;
// }
//
// void showSigSet(const sigset_t* set)
// {
//     cout << "pending: ";
//     for (int sig = 1; sig < 32; sig++)
//     {
//         if (sigismember(set, sig))
//             cout << "1";
//         else
//             cout << "0";
//     }
//     cout << '\n';
// }
//
// int main()
// {
//     signal(SIGINT, handler);
//
//     sigset_t set;
//     sigset_t pset;
//     sigemptyset(&set);
//     sigemptyset(&pset);
//
//     sigaddset(&set, SIGINT);
//     sigprocmask(SIG_BLOCK, &set, nullptr);
//
//     int cnt = 0;
//     while (true)
//     {
//         sigpending(&pset);
//         showSigSet(&pset);
//
//         if (cnt++ == 10)
//         {
//             cout << "unblock signals" << endl;
//             sigprocmask(SIG_UNBLOCK, &set, nullptr);
//             cnt = 0;
//         }
//         sleep(1);
//     }
//
//     return 0;
// }
//

// int main()
// {
//     signal(1, SIG_IGN);
//     pid_t id = fork();
//     if (id == 0)
//     {
//         std::cout << "segmentation fault" << std::endl;
//         int* p = nullptr;
//         *p = 100;
//
//         exit(0);
//     }
//
//     int status = 0;
//     waitpid(id, &status, 0);
//     std::cout << "exit code: " << (status >> 8) << std::endl;
//     std::cout << "exit signal: " << (status & 0x7F) << std::endl;
//     std::cout << "core dump: " << ((status >> 7) & 1) << std::endl;
// }


// int main()
// {
//     while (true)
//     {
//         std::cout << "i am normal process" << getpid() << std::endl;
//         sleep(1);
//     }
//
//     return 0;
// }

// int main()
// {
//     // signal(11, handler);
//     //
//     // *(int*)11223344 = 1;
//
//     signal(8, handler);
//     int a = 0;
//     a /= 0;
//
//     return 0;
// }

//
// int cnt = 0;
//
// int main()
// {
//     signal(SIGALRM, handler);
//     alarm(1);
//
//     // while (true)
//     // {
//     //     sleep(10);
//     // }
//
//     sleep(100);
//
//     return 0;
// }

// int main()
// {
//     int cnt = 1;
//     alarm(cnt);
//
//     while (true)
//     {
//         std::cout << "remaining time: " << cnt-- << std::endl;
//         sleep(1);
//     }
//
//     return 0;
// }


// int main()
// {
//     if (fork() == 0)
//     {
//         std::cout << "i am child process" << std::endl;
//         abort();
//     }
//
//     int status = 0;
//     waitpid(-1, &status, 0);
//     std::cout << "exit code: " << (status >> 8) << ", signal: " << (status & 0x7F) << endl;
//
//     return 0;
// }


// int main()
// {
//     signal(SIGINT, handler);
//
//     while (true)
//     {
//         cout << "i am a process, pid: " << getpid() << endl;
//         sleep(1);
//         raise(SIGINT);
//     }
//
//     return 0;
// }

// int main()
// {
//     for (int i = 1; i < 32; i++)
//     {
//         signal(i, handler);
//     }
//
//     while (true)
//     {
//         cout << "i am a process, pid: " << getpid() << endl;
//         sleep(1);
//     }
//
//     return 0;
// }
